<template>
  <div class="box">
  </div>
</template>
<script>

import * as THREE from "three";
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
//引入性能监视器stats.js
import Stats from 'three/examples/jsm/libs/stats.module.js';
console.log('Stats',Stats);
let w=window.innerWidth;
let h=window.innerHeight;
// 一。创建三维场景对象Scene
const scene = new THREE.Scene();
// scene.background = new THREE.Color('#aaaaaa');
let mesh=null;
// 性能测试[模型越多帧率越低性能越卡]
let nums=8000;
for (let i = 0; i < nums; i++) {
  // 给场景加物体
// 1.定义物体的形状：长方体 width height depth【深度】
const geometry = new THREE.BoxGeometry(2, 2, 2);
// 2.定义物体的材质：颜色（统一颜色）
// const mesbasic=new THREE.MeshBasicMaterial({color: 0x00ffff}); 基础网格材质【不受光照影响】
// const mesbasic=new THREE.MeshLambertMaterial({color: 0x00ffff});//漫反射网格材质 [受光照印象]
const mesbasic=new THREE.MeshPhongMaterial( {color: 0x00ffff} );//高光网格材质 [受光照印象]
// 为每个面创建不同的材质
// const materials = [
//     new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.5 }), // 右面 - 红色
//     new THREE.MeshBasicMaterial({ color: 0x00ff00 , transparent: true, opacity: 0.5 }), // 左面 - 绿色
//     new THREE.MeshBasicMaterial({ color: 0x0000ff  , transparent: true, opacity: 0.5}), // 上面 - 蓝色
//     new THREE.MeshBasicMaterial({ color: 0xffff00 , transparent: true, opacity: 0.5 }), // 下面 - 黄色
//     new THREE.MeshBasicMaterial({ color: 0xff00ff  , transparent: true, opacity: 0.5}), // 前面 - 紫色
//     new THREE.MeshBasicMaterial({ color: 0x00ffff , transparent: true, opacity: 0.5 })  // 后面 - 青色
//   ];
// 3.创建一个网格模型，用于表示生活中的物体
mesh=new THREE.Mesh(geometry, mesbasic);
let x=(Math.random() - 0.1)*200;
let y=(Math.random() - 1.1)*200;
let z=(Math.random() - 2.1)*200;
// 3.3 设置物体相对于场景中的位置 (疑问：设置这个位置是需要注意什么吗，是随意还是按照规则？)(疑问2：默认值0 0 0具体是在哪个位置从哪里能看出来？【可以用生活中的例子来讲一下这里】)
mesh.position.set(x, y, z);//表示对象局部位置。默认值为(0, 0, 0)。
// 4.将物体放到场景中
scene.add(mesh);
}



// 添加辅助线
const axesHelper = new THREE.AxesHelper(200);
axesHelper.setColors(0xff0000, 0x00ff00, 0x0000ff);
scene.add( axesHelper );

//a 创建一个点光源
const pointLight = new THREE.PointLight(0xffffff, 1.0);
pointLight.decay = 0;// 0不随着光照距离的远而衰减
// 光源放的位置
pointLight.position.set(200, 100, 200);
// scene.add(pointLight);
//b 光源辅助观察[可视化点光源] 参数：light 灯对象  size 点的尺寸
const pointLightHelper = new THREE.PointLightHelper(pointLight, 5);
scene.add(pointLightHelper);
//c 环境光:没有特定方向，整体改变场景的光照明暗
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);

//d 添加一个平行光
const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set(80, 140, 10);
// directionalLight.target=mesh;
scene.add( directionalLight );
//e 可视化平行光
const dirLightHelper = new THREE.DirectionalLightHelper(directionalLight, 5 ,0xFFC0CB );
scene.add(dirLightHelper);
// 二。创建相机 （相机是3D场景中用于观察的“眼睛”）[角度, 宽高比, 截取距离的最近距离, 截取距离的最远距离]（疑问：这个相机是在场景里面还是外面？）
const camera=new THREE.PerspectiveCamera(45, w / h, 0.1, 10000);
// 两个坐标连成一条线（就是视线）
// 相机的摆放位置
camera.position.set(250, 150, 250);
// 相机的目标视线
camera.lookAt(mesh.position);
// 三。 渲染器(类似于咔拍照动作)
const render=new THREE.WebGLRenderer();
render.setSize(w, h);
render.render(scene, camera);
console.log('render.domElement',render.domElement);
// document.body.appendChild(render.domElement);
// 涉及到旋转 缩放 移动 则需要引入轨道控制器 params1 改变相机参数  params2 渲染范围
const controls = new OrbitControls( camera, render.domElement );
controls.addEventListener( 'change', function () {
  console.log('look');
  render.render( scene, camera );
} );
// 实例化一个帧率器
const stats = new Stats();
console.log('stats',stats);
stats.setMode(1);
document.body.appendChild(stats.domElement);
// 渲染循环
function animate() {
  stats.update();
  //下面之所以能转动，他的本质是这样的【 mesh.rotation.y += 0.01;】 
  mesh.rotateY(0.01);
	render.render( scene, camera );// 周期性执行渲染， 更新canvas画布内容
  // 周期性的执行animate函数 
	requestAnimationFrame( animate );
}
animate()

 
export default{
  mounted() {
    document.querySelector('.box').appendChild(render.domElement);
    this.followWinChange();
  },
  beforeDestroy() {
 if (render &&render.domElement) {
      render.dispose();
    }
  },
  methods: {
    followWinChange() {
      // 监听窗口变化
      window.addEventListener('resize', function () {
        w = window.innerWidth;
        h = window.innerHeight;
          // 更新渲染器
        render.setSize(w, h);
        // 更新摄像头
        camera.aspect = w / h;
        // 更新摄像机的投影矩阵,任何参数被改变以后必须被调用
        camera.updateProjectionMatrix();
      })
    }
  }
}
</script>
<style scoped>

</style>